package platform

import (
	"context"
	"encoding/json"
	"fmt"
	"io"
	"net/http"

	hyperNexusCommon "github.com/wzh200x/hyperNexus/hyperNexusCommon"
	"github.com/wzh200x/hyperNexus/hyperNexusErr"
	"github.com/wzh200x/hyperNexus/hyperNexusProtocol/interfaceServerProtocol"
	"github.com/wzh200x/hyperNexus/hyperNexusType"
)

// 微信登录返回的会话信息
type OppoSession struct {
	Code  int          `json:"errCode"`
	Msg   string       `json:"errMsg"`
	Datat OppoUserData `json:"userInfo"`
}

type OppoUserData struct {
	OpenId        string `json:"userId"`
	UserName      string `json:"userName"`
	Avatar        string `json:"avatar"`
	Location      string `json:"location"`
	Constellation string `json:"constellation"`
	Age           string `json:"age"`
	Sex           string `json:"sex"`
}

type PlatformOppo struct {
	PlatformBase
}

func (p *PlatformOppo) Login(ctx context.Context, input *interfaceServerProtocol.LoginRequest) (output interfaceServerProtocol.LoginResponse, err error) {
	// 1. 通过code获取微信会话信息
	session, err := p.GetSession(input.PrivateKey, input.AppSecret, input.PackageName, input.Code)
	if err != nil {
		output.Code = hyperNexusErr.ErrCode_PlatformLoginFailed
		output.Msg = err.Error()
		return output, err
	}
	output.Code = 0
	output.OpenId = session.Datat.OpenId
	return output, nil
}

// 通过code获取微信会话信息
func (p *PlatformOppo) GetSession(privateKey string, appSecret string, packageName string, code string) (*OppoSession, error) {
	nowTime := hyperNexusCommon.GetCurrentTimeMilliseconds()
	signStr := fmt.Sprintf("`appKey=%s&appSecret=%s&pkgName=%s&timeStamp=%d&token=%s`",
		privateKey, appSecret, packageName, nowTime, code)
	signature := hyperNexusCommon.MD5Hex(signStr)
	url := fmt.Sprintf("https://play.open.oppomobile.com/instant-game-open/userInfo?pkgName=%s&token=%s&timeStamp=%d&sign=%s&version=1.0.0",
		packageName, code, nowTime, signature)

	resp, err := http.Get(url)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	var session OppoSession
	if err := json.Unmarshal(body, &session); err != nil {
		return nil, err
	}

	if session.Code != 0 {
		return nil, fmt.Errorf("OppoAPI错误: %d %s", session.Code, session.Msg)
	}

	return &session, nil
}

func NewPlatformOppo() *PlatformOppo {
	return &PlatformOppo{
		PlatformBase: PlatformBase{
			PlatformID: hyperNexusType.PlatformTypeOppo,
		},
	}
}
